;/******************************************************************************
;//             INTEL CORPORATION PROPRIETARY INFORMATION
;//  This software is supplied under the terms of a license agreement or
;//  nondisclosure agreement with Intel Corporation and may not be copied
;//  or disclosed except in accordance with the terms of that agreement.
;//        Copyright (c) 2000 Intel Corporation. All Rights Reserved.
;//
;//  VSS: 
;//     $Workfile: $
;//     $Revision: $
;//     $Date:     $
;//     $Archive:  $
;//
;//  Description:
;//      Intel(R) Integrated Performance Primitives - JPEG codec file.
;//      This file contains hufman encoding functions.
;//
;//  History:
;//     Date        Author        Changes
;//     2000/12/22  Jerry Hu      Created
;//
;********************************************************************************/

;******************************************************************************
; FUNCTION:   _MERGEBITS
; PARAMETERS: [out] ssss  - SSSS to be returned.
;	          [in]  data  - input data.
;	          [in]  csize - CSize table
;             [in|  temp  - temp
;******************************************************************************
    MACRO
   _MERGEBITS $usvalue, $usvaluebits, $svalue, $svaluebits, $temp
    CMP       $svaluebits, #0
    BEQ       %F9
	MOV		  $temp,    #1
	RSB		  $temp,    $temp,   $temp, LSL $svaluebits
    ADD       $usvaluebits,  $usvaluebits,   $svaluebits
    AND       $svalue,  $svalue,  $temp
    ORR       $usvalue, $svalue, $usvalue, LSL $svaluebits
9
    MEND

;******************************************************************************
; FUNCTION:   _GETSSSS
; PARAMETERS: [out] ssss  - SSSS to be returned.
;	          [in]  data  - input data.
;	          [in]  csize - CSize table
;             [in|  temp  - temp
;******************************************************************************
    MACRO
   _GETSSSS   $ssss, $data, $csize, $temp
    CMP     $data,  #0
    BGE     %F9
    RSB     $temp,  $data,   #0             ;-data
    CMP     $data,  #-256
    LDRGTB  $ssss,  [$csize, $temp]         ;ssss=_csize[-data]
    LDRLEB  $ssss,  [$csize, $temp, lsr #8]
    SUB     $data,  $data,   #1             ;data-=1; 
    ADDLE   $ssss,  $ssss,   #8             ;ssss=_csize[(-data)>>8]+8
    B       %F1
9    
    CMP     $data,  #255
    LDRLEB  $ssss,  [$csize, $data]         ;ssss=_csize[data]
    LDRGTB  $ssss,  [$csize, $data, lsr #8] ;ssss=_csize[(data)>>8]
    ADDGT   $ssss,  $ssss,   #8             ;ssss=_csize[(data)>>8]+8
1
    MEND

;******************************************************************************
; FUNCTION:   _WriteStreamBits
; PARAMETERS: [in] value   - value to be written (must be unsigned)
;	          [in] bits    - Validate number of bits of value
;	          [in] fbits   - Free bits used for the current pDst
;             [in|out]pdst - Current pDst point
;             [in|out]dst  - Current pDst value
;             [in]temp     - temp
;******************************************************************************

    MACRO
   _WriteStreamBits $value, $bits, $fbits, $pdst, $dst, $temp

    CMP    $bits,  $fbits                           ; if(nBits>=nFreeBitsLen)
    BLT    %F9
1

    SUB    $bits,  $bits,   $fbits                  ; nBits-=nFreeBitsLen

    MOV	   $temp,  $value, LSR $bits			    ; $temp = $value >> $bits
	
    MOV    $fbits, #8

    ORR    $dst,   $dst,    $temp				    ; data|=value
    STRB   $dst,   [$pdst], #1						; save dst and update pdst

    SUB	   $value, $value, $temp, LSL $bits		    ; clear the header bits of value


    MOV	   $temp,  #0
    CMP	   $dst,   #0xFF							; if dst == 0x ff
    STREQB $temp,  [$pdst], #1	                    ; append 0

    MOV	   $dst,   #0                               ; dst = 0

    CMP    $bits,  #8                               ; if(nBits>=nFreeBitsLen)

    BGE    %B1

9   
    CMP    $bits,  #0
    SUBGT  $fbits, $fbits,  $bits                   ; nFreeBitsLen-=nBits
    ORRGT  $dst,   $dst,    $value, LSL $fbits      ; data|=value

    MEND

;******************************************************************************
; Name:             _EncodeEOBRUN
; Description:      Encode EOB run length.
; Input Arguments:  
;           eobRun: Indicates EOB run length.
;            ppDst: Identifies output stream buffer
;      pDstBitsLen: Specifies the bits length that has been used 
;                   the stream buffer.
;        pHuffSize: Identifies huffman size buffer.
;
; Output Arguments:
;            ppDst: Identifies output stream buffer
;      pDstBitsLen: Identifies the updated bits length that has been used 
;                   the stream buffer.
;                  
; Returns:          
;                   none.
;
; REGISTERS:  
;             R0	eobRun
;             R1	pDst
;			  R2	*pDstBitsLen
;			  R3	pHuffSize
;			  R4	pHuffCode
;             R5	_eobsize, *pDst
;			  R6	rrrr
;			  R7	rs
;			  R8    val
;			  R9	nbits
;			  R10	fbits
;******************************************************************************

	MACRO   
   _EncodeEOBRUN $eobRun, $huffSize, $freeBitsLen, $pDstBuf, $dstBuf, $eobsize, $tmp0, $tmp1, $tmp2, $tmp3

	MOV     $tmp1,     $eobRun
	CMP     $tmp1,     #256
	LDRLTB  $tmp2,     [$eobsize,  $tmp1]             ; ssss=eobsize[eobRun] if(eobRun<256)
	MOVGE   $tmp1,     $tmp1,      LSR #0x08	      ; eobRun>>8 if (eobRun<256)
	LDRGEB  $tmp2,     [$eobsize,  $tmp1]             ; ssss=eobsize[eobRun]
	ADDGE   $tmp2,     $tmp2,      #0x08              ; ssss=eobsize[eobRun]+8
	MOV     $tmp0,     $tmp2,      LSL #4             ; rs=ssss|0000

	LDRB    $tmp1,     [$huffSize, $tmp0]		      ; nBits=huffSize[rs];
	MOV     $tmp0,     $tmp0,      LSL #0x01	    
	ADD     $tmp0,     $tmp0,      #256	    
	LDRH    $tmp0,     [$huffSize, $tmp0]	          ; val=huffCode[rs];

    _MERGEBITS $tmp0, $tmp1, $eobRun,    $tmp2, $tmp3
    ;_MERGEBITS $usvalue, $usvaluebits, $svalue, $svaluebits, $temp
	_WriteStreamBits   $tmp0, $tmp1, $freeBitsLen, $pDstBuf, $dstBuf, $tmp3

	MOV        $eobRun,  #0x0

	MEND

;******************************************************************************
; Name:             _AppendBits
; Description:      Append bits into stream.
; Input Arguments:  
;    pSrcBitBuffer: Identifies bits buffer which size shall be larger than 256+1024;
;       srcBitsLen: Identifies the current bits length in pSrcBitBuffer.
;
; Output Arguments:
;       pDstBuffer: Identifies output stream buffer.
;          pDstLen: Specifies the bits length that has been used 
;                   the stream buffer.
;                  
; Returns:          
;                   none.
; REGISTERS:  
;             R0	pSrcBitBuf (contains 0 or 1 only); Pointer will be moved.
;             R1	srcBitsLen (Must be > 0)
;			  R2	pDstBuf (pointer to current position)
;			  R3	freeBitsLen (free bits in the current pDstBuf[0]), It must be > 0 
;******************************************************************************
	MACRO 
   _AppendBits $pSrcBitBuf, $srcBitsLen, $freeBitsLen, $pDstBuf, $dstBuf, $tmp0
	
    LDRB    $tmp0,        [$pSrcBitBuf],    #0x01            ; get pSrcBitBuf[0]
9	
    SUBS    $freeBitsLen, $freeBitsLen,     #0x01
    MOV     $tmp0,        $tmp0,            LSL $freeBitsLen ; Move to the current bit position
	ORR     $dstBuf,      $tmp0,            $dstBuf		     ; Appending
	STRLEB  $dstBuf,      [$pDstBuf],       #0x01            ; Write back
	BGT     %F8
	CMP     $dstBuf,      #0xFF
	MOV     $dstBuf,      #0x0
	STREQB  $dstBuf,      [$pDstBuf],       #0x01            ; Write back 0xFF->0x00
	MOV     $freeBitsLen, #0x08 
8
	SUBS    $srcBitsLen,  $srcBitsLen,      #0x01
	LDRGTB  $tmp0,        [$pSrcBitBuf],    #0x01            ; get pSrcBitBuf[0]
	BGT     %B9 
	MOV     $srcBitsLen,  #0
	MEND 

; /* EOF */
    END
